package mutation;

import java.util.Random;

import individuals.Individual;

public class ClassicMutation {

	private static Random r = new Random(127);
	public Double Pmut;

	public ClassicMutation(Double pmut) {
		super();
		Pmut = pmut;
	}
	
	/**Recibo un individuo y lo muta, hay que meter la aptitud. Retorna el mismo individuo pero mutado
	 */
	public Individual mutate(Individual ind){
		
		Double d = ind.getGen();
	
		long longD = d.doubleToRawLongBits(d);
//		System.out.println("antes:"+printBits(Double.doubleToRawLongBits(ind.getGen())));
		
		double rand;
		int a =0;
		for(int i=0; i<64; i++){
			rand = r.nextDouble();
			if (rand < Pmut) {
				a++;
				long bitToChange = 0x0000000000000001L << i;
                if ((longD & bitToChange) == 0) 
                        longD = longD | bitToChange; /*se cambia un 0*/
                else 
                	longD = longD & (~bitToChange);/*se cambia un 1*/
			}
			
		}
		Double iNum = Double.longBitsToDouble(longD);
//		System.out.println("se modifican "+a);
		iNum = Math.floor(iNum)%6 + (iNum-Math.floor(iNum));
//		System.out.println("modif:"+printBits(Double.doubleToRawLongBits(iNum)));
		ind.setGen(iNum);
		/*Hay que setear la nueva aptitud*/
		ind.setAptitud(Individual.getFunc().evaluate(ind.getGen()));
		
		return ind;
	}
	
	private String printBits(long bits) {
		long one = 0x0000000000000001L;
		String s="";
		
		for(int i=0; i<64; i++) {
			s+=((bits&one)==0)?0:1;
			bits>>>=1;
		}
		return s;
	}
	
}
